
// Copyright (C) 2007 Richard Uhler
// This file is part of Esiply.
//
// Esiply is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License, Version 2,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

//#include <gc_allocator.h>

#include "Block.h"
#include "Completion.h"
#include "Null.h"
#include "String.h"
#include "Object.h"
#include "Scope.h"


Block::Block(){
	m_sync = 0;
	m_this = 0;
	m_id = 0;
}
Value* Block::execute_internal(Scope* scope) const
{
	Object* syncObj = NULL;
	//start synchronized
	if(m_sync == 1){
		if(m_this == 1){
			syncObj = scope->get_this()->getValue()->object();
		}else{
			syncObj = scope->lookup(m_id)->getValue()->object();
		}
		syncObj->lock();
	}
    // Execute all of the statements.
    for (std::vector<Statement*>::const_iterator iter = m_statements.begin(); iter != m_statements.end(); iter++)
    {
        Value* comp = (*iter)->execute(scope);
        if (comp->completion()->type() != CT_NORMAL)
        {
            return comp;
        }
    }
	//finish synchronized
	if(m_sync == 1){
		syncObj->unlock();
	}
    return new Completion(CT_NORMAL, Null::null, Completion::empty);
}

void Block::push_back(Statement* statement)
{
    m_statements.push_back(statement);
}

void Block::getDeclaredVariables(std::vector<String*>& ids) const
{
    for (unsigned int i = 0; i < m_statements.size(); i++)
    {
        m_statements[i]->getDeclaredVariables(ids);
    }
}

int Block::get_sync() const{

	return m_sync;
}

void Block::set_sync(int sync) {

	m_sync = sync;
}
void Block::set_this(int isThis) {
	m_this = isThis;
}
void Block::set_id(String* id) {

	m_id = id;
}